﻿// Manages the user account in the application
define([
    'Wjs/flow/Flow',
    'Wjs/ui/widgets/Dialog',
    'Wjs/ui/widgets/forms/AjaxForm',
    'Wjs/ui/widgets/fields/HiddenField',
    'Wjs/ui/widgets/fields/TextField',
    'Wjs/ui/widgets/fields/Password'
],
function () {
    'use strict';

    return Wjs.defineOnce({

        type: 'accountManager',

        internal: {

            'static': true,

            construct: function () {

                this.loginUrl = '/Token';

                this.registerUrl = '/api/Account/Register';

                this.logoutUrl = '/api/Account/Logout';

                this.getUserInfoUrl = 'api/Account/UserInfo';

                this.changePasswordUrl = 'api/Account/ChangePassword'
            }
        },

        tokenKey: 'accessToken',

        //#region Log In

        ensureLogin: function (callback, scope) {

            if (!this.isLoggedIn()) {

                this.login(callback, scope);
            }
            else {

                scope = scope || this;
                callback.call(scope);
            }
        },

        login: function (callback, scope) {
            var me = this,

                form = Wjs.new('AjaxForm')
                        .setHttpRequest(

                             Wjs.new('HttpRequest')
                                .setMethod('post')
                                .setUrl(me.loginUrl)
                                .onError(function (error, requestData) {
                                    var data,
                                        text;

                                    if (!Wjs.isJSON(error.text)) { // Pass the error HTML page from the server

                                        text = error.text;
                                    }
                                    else {

                                        data = JSON.parse(error.text);

                                        switch (data.error) {

                                            case 'invalid_grant':
                                                {
                                                    text = 'Invalid user name or password';
                                                }
                                                break;

                                            default:
                                                {
                                                    text = data.error;
                                                }
                                                break;
                                        }
                                    }

                                    Wjs.alert()
                                        .setTitle(error.description)
                                        .setContent(text)
                                        .show();
                                })
                        )
                        .setEncodingType('application/x-www-form-urlencoded')
                        .addItem(

                            Wjs.new('HiddenField')
                                .setName('grant_type')
                                .setValue('password')
                        )
                        .addItem(

                            Wjs.new('LabeledField')
                                .setTextLabel('User name')
                                .setField(

                                    Wjs.new('TextField')
                                        .setName('username')
                                )
                        )
                        .addItem(

                            Wjs.new('LabeledField')
                                .setTextLabel('Password')
                                .setField(

                                    Wjs.new('Password')
                                        .setName('password')
                                )
                        )
                        .addItem(

                            Wjs.new('Button')
                                .setText('Register as a new user')
                                .onClick(function (evt) {

                                    evt.preventDefault();

                                    me.register();
                                })
                        ),

                dialog = Wjs.new('Dialog')
                            .setWidth(300)
                            .setTextTitle('Please Login')
                            .addBodyItem(form)
                            .addButton(

                                Wjs.new('Button')
                                    .setText('Login')
                                    .onClick(function () {

                                        form.submit();
                                    })
                            )
                            .addButton('cancel');

            form.onSubmit(function (response) { // response returned from the server

                dialog.close();

                response = JSON.parse(response.text);

                sessionStorage.setItem(me.tokenKey, response.access_token);

                if (callback) {

                    callback.call(scope);
                }
            })

            dialog.render()
                  .show();
        },

        isLoggedIn: function () {

            return sessionStorage.getItem(this.tokenKey);
        },

        //#endregion

        register: function () {

            var me = this,

                form = Wjs.new('AjaxForm')
                        .setHttpRequest(

                             Wjs.new('HttpRequest')
                                .setMethod('post')
                                .setUrl(me.registerUrl)
                                .addHeader('Content-Type', 'application/json; charset=utf-8')
                                .onError(function (error, requestData) {
                                    var data = JSON.parse(error.text),
                                        text = '',
                                        errors,
                                        length,
                                        i;

                                    if (data.ModelState) {

                                        for (var name in data.ModelState) {

                                            errors = data.ModelState[name];

                                            length = errors.length;

                                            for (i = 0; i < length; ++i) {
                                                text += errors[i] + '\n';
                                            }
                                        }
                                    }
                                    else {
                                        text = data.Message;

                                        console.log(data.MessageDetail || data.Message);
                                    }

                                    Wjs.alert()
                                        .setTitle(error.description)
                                        .setContent(text)
                                        .show();
                                })
                        )
                        .addItem(

                            Wjs.new('LabeledField')
                                .setTextLabel('Email')
                                .setField(

                                    Wjs.new('TextField')
                                        .setName('email')
                                )
                        )
                        .addItem(

                            Wjs.new('LabeledField')
                                .setTextLabel('Password')
                                .setField(

                                    Wjs.new('Password')
                                        .setName('password')
                                )
                        )
                        .addItem(

                            Wjs.new('LabeledField')
                                .setTextLabel('Confirm Password')
                                .setField(

                                    Wjs.new('Password')
                                        .setName('confirmpassword')
                                )
                        ),

                dialog = Wjs.new('Dialog')
                            .setWidth(300)
                            .setTextTitle('Please Register')
                            .addBodyItem(form)
                            .addButton(

                                Wjs.new('Button')
                                    .setText('Register')
                                    .onClick(function () {

                                        form.submit();
                                    })
                            )
                            .addButton('cancel');

            form.onSubmit(function (response) { // response returned from the server

                dialog.close();

                Wjs.alert()
                    .setTitle('Success')
                    .setContent('Registration successful')
                    .show();
            });

            dialog.render()
                  .show();
        },

        addAuthorization: function (headers) {
            var token = sessionStorage.getItem(this.tokenKey);

            if (token) {

                headers = headers || {};

                headers.Authorization = 'Bearer ' + token;
            }
            else {

                throw 'Log in required';
            }
        },

        getUserInfo: function (callback, scope) {

            scope = scope || this;

            Wjs.new('HttpRequest')
                .setUrl(this.getUserInfoUrl)
                .onSuccess(function (response) {

                    callback.call(scope, response);
                })
                .send();
        },

        changePassword: function () {

        },

        logout: function (callback, scope) {

            Wjs.new('HttpRequest')

                .setMethod('post')

                .setUrl(this.logoutUrl)

                .onSuccess(function (response) {

                    console.log(response); // Don't wait for a return to handle the callback
                })

                .send();

            sessionStorage.removeItem(this.tokenKey);

            scope = scope || this;

            if (callback) {

                callback.call(scope);
            }

        }

    });

});